library SaveCommand initializer init requires LegacySystem, LoadCommand

	globals
		private string array LastCode
		private string array LastCodePretty
		private integer array SaveAttempts
	endglobals

	private function PushData takes Savecode s, integer pid returns nothing
        local integer xp = R2I(udg_Experience[pid])
        local integer MOS = GetI("player mos", pid)
        local integer CR = GetPlayerTechCount(Player(pid-1), 'R015', true)
        local integer service1 = GetI("service1", pid)
        local integer service2 = GetI("service2", pid)
        local integer service3 = GetI("service3", pid)
        local integer service4 = GetI("service4", pid)
        local integer combat1 = GetI("combat1", pid)
        local integer combat2 = GetI("combat2", pid)
        local integer combat3 = GetI("combat3", pid)
        local integer combat4 = GetI("combat4", pid)
        local integer combat5 = GetI("combat5", pid)
        local integer MOH = GetI("MOH", pid)
        local integer DIR = GetI("DIR", pid)

		local integer hits = udg_PlayerHitsTaken[pid]
		local integer kills = GetPlayerScore(Player(pid-1), PLAYER_SCORE_UNITS_KILLED)
		local integer bonusKills = 0
		local boolean article = udg_Article15[pid]
		local boolean mohpreqs = false
		
		if udg_SectorClear then
			if kills < 450 then
				// up to 230 bonus kills if win game (decreases as closing to 450)
				set bonusKills = R2I(230.0*(450.0 - I2R(kills))/450.0)
			endif
			if udg_LostCause then // won LC, give them some credit.
				set hits = 0
			else
				set hits = R2I(I2R(hits) * 0.5)
			endif
			
			if udg_Difficulty >= 4.0 then
				set bonusKills = bonusKills + 50
			endif
		endif
		set kills = kills + bonusKills
		
		if udg_MissionsCompleted >= 4 then
			set hits = R2I(I2R(hits) * 0.80)
		elseif udg_MissionsCompleted >= 3 then
			set hits = R2I(I2R(hits) * 0.90)
		endif
		if udg_Difficulty >= 4.0 and udg_MissionsCompleted >= 2 then
			set hits = R2I(I2R(hits) * 0.80)
		endif
		
		// lt cols and above can only xp up in NM
		if xp > 180000 and udg_Difficulty < 4.0 then
			set xp = R2I(udg_InitialExperience[pid])
		endif
		call TriggerSleepAction(0.1)
		
		if udg_InitialPlayers >= 4 then

			if hits <= 25 and kills >= 250 and not article then
				if combat1 < 6 then
					set combat1 = combat1 + 1
				endif
			elseif combat1 > 0 and GetRandomInt(0,100) <20 then
				set combat1 = combat1 - 1
			endif

			if hits <= 24 and kills >= 250 and udg_MissionsCompleted >= 2 and not article then
				if combat2 < 6 then
					set combat2 = combat2 + 1
				endif
			elseif combat2 > 0 and GetRandomInt(0,100) <20 then
				set combat2 = combat2 - 1
			endif
			
			// double bonus
			if udg_MissionsCompleted>= 4 and not article then
				if combat1 < 6 then
					set combat1 = combat1 + 1
				endif
				if combat2 < 6 then
					set combat2 = combat2 + 1
				endif
			endif
			
			if hits <= 23 and kills >= 350 and udg_MissionsCompleted >= 2 and not article then
				if combat3 < 6 then
					set combat3 = combat3 + 1
				endif
			elseif combat3 > 0 and GetRandomInt(0,100) <20 then
				set combat3 = combat3 - 1
			endif

			if hits <= 22 and kills >= 450 and udg_MissionsCompleted >= 2 and not article then
				if combat4 < 6 then
					set combat4 = combat4 + 1
				endif
			elseif combat4 > 0 and GetRandomInt(0,100) <20 then
				set combat4 = combat4 - 1
			endif

			if hits <= 21 and kills >= 450 and udg_MissionsCompleted >= 3 and not article then
				if combat5 < 6 then
					set combat5 = combat5 + 1
				endif
			elseif combat5 > 0 and GetRandomInt(0,100) <20 then
				set combat5 = combat5 - 1
			endif
			
			// just need to survive to the wave ._.
			if udg_ServiceMedalBoolean[1] and not article then
				if service1 < 6 then
					set service1 = service1 + 1
				endif
			elseif service1 > 0 and GetRandomInt(0,100) <15 and not udg_SectorClear then
				set service1 = service1 - 1
			endif
			
			if udg_ServiceMedalBoolean[2] and udg_MissionsCompleted >= 1 and not article then
				if service2 < 6 then
					set service2 = service2 + 1
				endif
			elseif service2 > 0 and GetRandomInt(0,100) <15 and not udg_SectorClear then
				set service2 = service2 - 1
			endif
			
			if udg_ServiceMedalBoolean[3] and udg_MissionsCompleted >= 2 and not article then
				if service3 < 6 then
					set service3 = service3 + 1
				endif
			elseif service3 > 0 and GetRandomInt(0,100) <15 and not udg_SectorClear then
				set service3 = service3 - 1
			endif
			
			if udg_ServiceMedalBoolean[4] and udg_MissionsCompleted >= 3 and not article then
				if service4 < 6 then
					set service4 = service4 + 1
				endif
			elseif service4 > 0 and GetRandomInt(0,100) <15 and not udg_SectorClear then
				set service4 = service4 - 1
			endif

			if udg_SectorClear and udg_ServiceMedalBoolean[4] and not article then
				set mohpreqs = mohpreqs or (udg_LostCause and kills >=370 and udg_MissionsCompleted >= 3) 
				set mohpreqs = mohpreqs or (kills >= 450 and udg_MissionsCompleted >= 4)	
				set mohpreqs = mohpreqs or (kills >= 400 and udg_MissionsCompleted >= 3 and udg_Difficulty >= 4.0)
				if mohpreqs then
					if MOH < 6 then
						set MOH = MOH + 1
					endif
				endif
			endif

			if xp >= 10000 and udg_ServiceMedalBoolean[5] then
				if DIR < 6 then
					set DIR = DIR + 1
				endif
			endif
		endif

		if udg_SectorClear  then
			if CR < 7 then
				set CR = CR + 1
			endif
		else
			if GetRandomInt(0,100) < 25 and CR > 0 then
				set CR = CR - 1
			endif
		endif
			
		if MOS < 0 or MOS > 7 then
			set MOS = 0
		endif
		
		call TriggerSleepAction(0.1)
		
		set xp = s.Encode(xp, 1000000) 
		set combat1 = s.Encode(combat1,7)
		set combat2 = s.Encode(combat2,7)
		set combat3 = s.Encode(combat3,7)
		set combat4 = s.Encode(combat4,7)
		set combat5 = s.Encode(combat5,7)

		set service1 = s.Encode(service1,7)
		set service2 = s.Encode(service2,7) 
		set service3 = s.Encode(service3,7)
		set service4 = s.Encode(service4,7)
		
		set MOH = s.Encode(MOH,7)  
		set MOS = s.Encode(MOS,7)  
		set CR = s.Encode(CR,7)	
		set DIR = s.Encode(DIR,7)  
	endfunction
	
	private function Trig_test_savecode_Actions takes nothing returns nothing
		local Savecode savecode 
		local player p = GetTriggerPlayer()
		local integer i = GetPlayerId(p)
		local string pName = OriginalName[GetPlayerId(p) + 1]
		local string codeS 

		if udg_InitialPlayers < 2 then
			call DisplayTimedTextToPlayer(p,0.0,0.0,30.0, "Cannot register Biometric ID in solo mode." )
			return 
		endif
		
		set SaveAttempts[i] = SaveAttempts[i] + 1
		if SaveAttempts[i] > 3 then
			call DisplayTimedTextToPlayer(p,0.0,0.0,30.0, "Biometric ID registry limit reached (3)" )
			return 
		endif
		
		set savecode = Savecode.create()

		call PushData(savecode, GetPlayerId(p) + 1)
		set codeS = savecode.Save(pName, 2)
		//xxxxxx-yyyyyy

		set LastCode[i] = SubString(codeS, 0,6) + "-" + SubString(codeS,6, StringLength(codeS))
		set LastCodePretty[i] = savecode.colorize(LastCode[i])
		
		call DisplayTimedTextToPlayer(p,0.0,0.0,30.0, "Registered Biometric ID for " +pName+ " [" + LastCodePretty[GetPlayerId(p)] + "]" )
	endfunction
	
	private function code_Actions takes nothing returns boolean
		local player p = GetTriggerPlayer()
		if LastCodePretty[GetPlayerId(p)] != null then
			call DisplayTimedTextToPlayer(p,0.0,0.0,30.0, "Registered Biometric ID is [" + LastCodePretty[GetPlayerId(p)] + "]" )
		else
			call DisplayTimedTextToPlayer(p,0.0,0.0,5.0, "Biometric ID not registered yet.")
		endif
		
		set p = null
		return false
	endfunction 

	
	private function check_Actions takes nothing returns boolean
        local string raw = GetEventPlayerChatString()
        local string code1 = SubString(raw,7,StringLength(raw))
        local player p = GetTriggerPlayer()
		
		//"-check xxxxxx-yyyyyy"
		if LastCode[GetPlayerId(p)] == null then
		
		elseif LastCode[GetPlayerId(p)] == code1 then
			call DisplayTimedTextToPlayer(p,0.0,0.0,20.0, "[" + LastCodePretty[GetPlayerId(p)] + "] has been validated." )
			if GetLocalPlayer() == p  then
				call StartSound(gg_snd_ALICEBeep)
			endif
		else
			call DisplayTimedTextToPlayer(p,0.0,0.0,5.0, "Biometric ID not valid, last ID was [" + LastCodePretty[GetPlayerId(p)] + "]" )
		endif
		
        set p = null
		return false
	endfunction
	
	private function init takes nothing returns nothing
		local trigger t1
		local trigger t2
		local trigger t3
		
		local integer i = 0
        set t1 = CreateTrigger()
		set t2 = CreateTrigger()
		set t3 = CreateTrigger()
		loop
			exitwhen i > 11
				call TriggerRegisterPlayerChatEvent( t1, Player(i), "-save", true )
				call TriggerRegisterPlayerChatEvent( t2, Player(i), "-code", true )
				call TriggerRegisterPlayerChatEvent( t3, Player(i), "-check", false )
			set i = i + 1
		endloop
	
        call TriggerAddAction( t1, function Trig_test_savecode_Actions )
		call TriggerAddCondition( t2, Condition(function code_Actions) )
		call TriggerAddCondition( t3, Condition(function check_Actions ))
			
		set t1 = null
		set t2 = null
		set t3 = null
	endfunction

endlibrary